package com.my.mygaode.view

import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.os.Bundle
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.RelativeLayout
import androidx.core.widget.NestedScrollView
import com.amap.api.location.AMapLocation
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.LocationSource
import com.amap.api.maps.MapView
import com.amap.api.maps.model.CameraPosition
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.Marker
import com.amap.api.maps.model.animation.Animation
import com.amap.api.maps.model.animation.ScaleAnimation
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.*
import com.amap.api.services.geocoder.GeocodeSearch.OnGeocodeSearchListener
import com.my.mygaode.LocationHelper
import com.my.mygaode.MarkerHelper
import com.my.mygaode.R
import com.my.mygaode.bean.MarkerBean
import com.my.mygaode.screenHeight
import com.my.mygaode.screenWidth

/**
 * @ClassName MapContainerView
 * @Description
 * 1、地图控件自定义view
 * 2、回调经纬度信息
 * @Author mwj
 * @Date 2023/2/8 11:51
 * @Version 1.0
 *
 * 优化东西：
 * LocationSource不要 LocationHelper单例
 **/
class MapContainerView : RelativeLayout {

    companion object {
        const val MY_LOCATION_ID = "my_location_id"
        private const val SCALE_LEVEL = 18f
    }

    /**
     * 是否显示地图
     */
    private var isShowMap = false

    private var mListener //定位监听器
            : LocationSource.OnLocationChangedListener? = null
    private var mapView: MapView? = null
    private var aMap: AMap? = null

    private var myLatLng: LatLng? = null

//    private var geocoderSearch: GeocodeSearch? = null

    /**
     * 是否可以触摸操作地图
     */
    var isTouchToMap = true

    /**
     * 城市的位置发生变化回调
     */
    private var changCityCodeListener: (RegeocodeAddress?) -> Unit = { }

    /**
     * 获取当前位置的经纬度
     * @return LatLng
     */
    fun getLocationLatLng(): LatLng? {
        return myLatLng
    }

    private var scrollView: NestedScrollView? = null

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        init()
    }

    private var markerHelper: MarkerHelper? = null

    private fun init() {
        isShowMap = true
        View.inflate(context, R.layout.ly_map, this@MapContainerView)
        mapView = findViewById<MapView>(R.id.map_view)
        if (aMap == null) {
            aMap = mapView?.map
        }
        markerHelper = MarkerHelper(aMap!!)
//        geocoderSearch = GeocodeSearch(context)

        //设置缩放级别
        aMap?.moveCamera(CameraUpdateFactory.zoomTo(SCALE_LEVEL))
        //显示定位层并可触发，默认false
        aMap?.isMyLocationEnabled
        //下移高德LOG到屏幕外
        aMap?.uiSettings?.setLogoBottomMargin(-100);
        // 去掉高德地图右下角隐藏的缩放按钮
        aMap?.uiSettings?.isZoomControlsEnabled = false
        initListener()
        requestLocation()
    }

    private fun unListener() {
        aMap?.setOnCameraChangeListener(null)
    }

    private var iLocationCallBack: LocationHelper.ILocationCallBack? = null

    private fun initListener() {
        aMap?.setOnCameraChangeListener(object : AMap.OnCameraChangeListener {
            override fun onCameraChange(p0: CameraPosition) {
                mapToChang(p0)
            }

            override fun onCameraChangeFinish(p0: CameraPosition) {
                mapToChang(p0)
                //地图停止触摸
                markerHelper?.isUpdateShowMapMarkerAnimation = false
            }
        })
//        geocoderSearch?.setOnGeocodeSearchListener(object : OnGeocodeSearchListener {
//
//            /**
//             * 逆地理编码回调
//             * @param p0 RegeocodeResult
//             * @param p1 Int
//             */
//            override fun onRegeocodeSearched(result: RegeocodeResult?, rCode: Int) {
////                LogUtils.i(LogUtils.TAG_DATA,"onRegeocodeSearched--->"+result?.regeocodeAddress?.cityCode+","+rCode)
//                changCityCodeListener(result?.regeocodeAddress)
//            }
//
//            /**
//             * 地理编码查询回调
//             * @param p0 GeocodeResult
//             * @param p1 Int
//             */
//            override fun onGeocodeSearched(result: GeocodeResult?, rCode: Int) {
////                LogUtils.i(LogUtils.TAG_DATA,"onRegeocodeSearched--->"+result?.geocodeQuery?.toString()+","+rCode)
//            }
//
//        })
    }

    // 第一个参数表示一个Latlng，第二参数表示范围多少米，第三个参数表示是火系坐标系还是GPS原生坐标系
    val query = RegeocodeQuery(LatLonPoint(0.0, 0.0), 200f, GeocodeSearch.AMAP)

    private fun mapToChang(cameraPosition: CameraPosition) {
        markerHelper?.updateShowMapMarkerListInfo()
        query.point = LatLonPoint(cameraPosition.target.latitude, cameraPosition.target.longitude)
//        geocoderSearch?.getFromLocationAsyn(query) // 设置异步逆地理编码请求

    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (!isTouchToMap) { //不给地图触摸
            return false
        }
        if (ev.action == MotionEvent.ACTION_DOWN) {
            //地图开始触摸
            markerHelper?.isUpdateShowMapMarkerAnimation = true
        }
        return super.dispatchTouchEvent(ev)
    }

    fun setClickMarkerListener(listener: (MarkerBean?) -> Unit) {
        markerHelper?.setClickMarkerListener(listener)
    }

    fun setOnChangToCityCodeListener(listener: (RegeocodeAddress?) -> Unit) {
        changCityCodeListener = listener
    }

    /**
     *重新定位，位置
     */
    fun requestLocation() {
        if (!isShowMap) {
            return
        }
        try {
            if (iLocationCallBack == null) {
                iLocationCallBack = object : LocationHelper.ILocationCallBack {
                    override fun callBack(
                        code: String?,
                        str: String?,
                        lat: Double,
                        lgt: Double,
                        aMapLocation: AMapLocation?
                    ) {
                        //根据获取的经纬度，将地图移动到定位位置
                        Log.i("mygaode",
                            "MapContainerView收到位置信息回调---》${aMapLocation?.toString()}"
                        )
                        myLatLng = LatLng(lat, lgt)
                        aMap?.moveCamera(CameraUpdateFactory.changeLatLng(LatLng(lat, lgt)))
                        mListener?.onLocationChanged(aMapLocation)
                        mMapContainerViewBack?.updateMap()
                        LocationHelper.instance.stopLocation()
                    }
                }
                LocationHelper.instance.addLocationCallBack(iLocationCallBack!!)
            }
            LocationHelper.instance.startLocate()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun onCreate(savedInstanceState: Bundle?) {
        mapView?.onCreate(savedInstanceState) // 此方法必须重写
    }

    fun onResume() {
        isShowMap = true
        mapView?.onResume()
    }

    fun onPause() {
        isShowMap = false
        mapView?.onPause()
    }

    fun onDestroy() {
        unListener()
        LocationHelper.instance.stopLocation()
        if (iLocationCallBack != null) {
            LocationHelper.instance.removeLocationCallBack(iLocationCallBack!!)
            iLocationCallBack = null
        }
        markerHelper?.release()
        markerHelper = null
        mapView?.onDestroy()
    }

    fun onSaveInstanceState(outState: Bundle) {
        mapView?.onSaveInstanceState(outState)
    }

    /**
     *定位，将自己移至到map的中心点
     */
    fun moveMySelfCamera() {
        if (myLatLng == null) {
            requestLocation()
            return
        }
        moveCamera(myLatLng)
    }


    /**
     *将对应的经纬度移至到map的中心点
     * @param latLng LatLng?
     */
    fun moveCamera(latLng: LatLng?) {
        aMap?.moveCamera(CameraUpdateFactory.zoomTo(SCALE_LEVEL))
        aMap?.animateCamera(CameraUpdateFactory.changeLatLng(latLng), 100, null)
    }

    /**
     * true放大，false放小 一格
     * @param enlarge Boolean
     */
    fun slowScaleMap(enlarge: Boolean) {
        aMap?.moveCamera(if (enlarge) CameraUpdateFactory.zoomIn() else CameraUpdateFactory.zoomOut())
    }

    fun setScrollView(scrollView: NestedScrollView) {
        this.scrollView = scrollView
    }

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_UP) {
            scrollView?.requestDisallowInterceptTouchEvent(false)
        } else {
            scrollView?.requestDisallowInterceptTouchEvent(true)
        }
        return false
    }

    private var mMapContainerViewBack: MapContainerViewBack? = null

    fun setMapContainerViewBack(back: MapContainerViewBack?) {
        this.mMapContainerViewBack = back
    }

    interface MapContainerViewBack {
        fun updateMap()
    }

    /**
     * 更新自己位置的MarkerBean
     * @param view View
     * @param latLng LatLng
     */
    fun addMySelfMarkerBean(view: View, latLng: LatLng) {
        markerHelper?.addMarkerBean(MY_LOCATION_ID, view, latLng)
    }

    /**
     * 获取自己位置的MarkerBean
     * @return MarkerBean
     */
    fun getMySelfMarkerBean(): MarkerBean? {
        return markerHelper?.getIdToMarkerBean(MY_LOCATION_ID)
    }

    /**
     * 图片地址
     * @param absolutePath String?
     * @return Marker?
     */
    fun addMarkerBean(
        id: String,
        absolutePath: String?,
        latLng: LatLng,
        isAdd: Boolean = true
    ): MarkerBean? {
        return markerHelper?.addMarkerBean(id, absolutePath, latLng, isAdd)
    }

    /**
     * 图片地址
     * @param absolutePath String?
     * @return Marker?
     */
    fun addMarkerBean(
        id: String,
        bitmap: Bitmap?,
        latLng: LatLng,
        isAdd: Boolean = true
    ): MarkerBean? {
        return markerHelper?.addMarkerBean(id, bitmap, latLng, isAdd)

    }


    /**
     * 添加一个自定义view的覆盖物
     * @param id String
     * @param view View
     * @param latLng LatLng
     * @param isAdd Boolean
     * @return MarkerOptions
     */
    fun addMarkerBean(id: String, view: View, latLng: LatLng, isAdd: Boolean = true): MarkerBean? {
        return markerHelper?.addMarkerBean(id, view, latLng, isAdd)

    }

    /**
     * 得到一个缓存MarkerBean ，没有就会创建一个MarkerBean
     * @param id String 作为根据得到缓存list里面的MarkerBean
     * @param isAdd Boolean 是否立即加入到地图上显示
     * @return MarkerBean
     */
    fun getIdToMarkerBean(id: String): MarkerBean? {
        return markerHelper?.getIdToMarkerBean(id)
    }

    /**
     * 添加一个覆盖物
     * @param marker MarkerOptions
     */
    fun addMarkerBean(marker: MarkerBean?) {
        markerHelper?.addMarkerBean(marker)
    }

    /**
     * 显示所有marker
     */
    fun showMarkers() {
        markerHelper?.showMarkers()
    }

    /**
     * 显示list集合的marker
     * @param list List<MarkerBean>?
     * @param isClearSelf Boolean
     */
    fun showListMarkers(list: List<MarkerBean>?, isClearSelf: Boolean = false) {
        clearMarkers(isClearSelf)
        addMarkerBeanList(list)
        showMarkers()
    }

    /**
     * 清除除了自己以外，所有的marker数据
     */
    fun clearMarkers(isClearSelf: Boolean = false) {
        var selfMarker = if (myLatLng == null) null else getIdToMarkerBean(MY_LOCATION_ID)
        markerHelper?.clearMarkers()
        if (selfMarker != null && !isClearSelf) {
            markerHelper?.addMarkerBean(selfMarker)
        }
    }

    /**
     * 多条MarkerOptions加入
     * @param list List<MarkerOptions>?
     */
    fun addMarkerBeanList(list: List<MarkerBean>?) {
        markerHelper?.addMarkerBeanList(list)
    }

    /**
     * 设置屏幕上的某个像素点为地图中心点
     * @param x Int
     * @param y Int
     */
    fun setPointToCenter(x: Int, y: Int) {
        aMap?.setPointToCenter(x, y);
    }

    /**
     * 处理自己位置动画放大缩小逻辑
     * @param shadow Boolean
     */
    fun clickMarkerToAnimation(shadow: Boolean, markerBean: MarkerBean?) {
        val x = (context as Activity).screenWidth() / 2
        val y = if (shadow && TextUtils.equals(
                markerBean?.id,
                MY_LOCATION_ID
            )
        ) (context as Activity).screenHeight() * 2 / 5 else (context as Activity).screenHeight() / 2
        setPointToCenter(x, y)
        moveCamera(markerBean?.markerOptions?.position)
        slowScaleMap(shadow)
        val marker = getShowMarker(markerBean?.markerId) ?: return
        val scaleF = if (TextUtils.equals(markerBean?.id, MY_LOCATION_ID)) 1.3f else 1.5f
        val markerAnimation = if (shadow) {// 缩放比例
            ScaleAnimation(1.0f, scaleF, 1.0f, scaleF)
        } else {
            ScaleAnimation(scaleF, 1.0f, scaleF, 1.0f)
        }
        markerAnimation.setDuration(100) // 动画时间
        // 动画之后保存的状态 0 动画之后的状态 1 动画之前的状态
        markerAnimation.fillMode = Animation.FILL_MODE_FORWARDS
        marker.setAnimation(markerAnimation) // 将动画赋值给当前的marker
        marker.startAnimation()
    }

    fun getShowMarker(markerId: String?): Marker? {
        return markerHelper?.getShowMarker(markerId)
    }
}